package org.yege.algorithm.loadtest;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author 业哥
 * java版Web性能压测工具
 * 需求：
 * 1.用java编程语言写一个 Web 性能压测工具，
 * 2.输入参数：URL，请求总次数，并发数。
 * 3.输出参数：平均响应时间，95% 响应时间。
 * 4.用这个测试工具以 10 并发、100 次请求压测
 *
 *
 */
public class MyLoadTestMain {
    /**
     * @param args
     * args[0]:参数1:并发数
     * args[1]:参数2:总请求数
     * args[2]:参数3:待压测url链接
     */
    public static void main(String[] args) {
        if(args==null||args.length!=3){
            System.err.println("参数为空,或者参数个数小于3");
            return;
        }
        int n1;//args[0]:参数1:并发数
        int n2;//args[1]:参数2:总请求数
        String loadUrl=args[2];//args[2]:待压测url链接
        try {
            n1=Integer.parseInt(args[0]);
            n2=Integer.parseInt(args[1]);
        }catch (Exception ex){
            System.err.println(ex.getMessage());
            return;
        }
        if(n2<n1){
            System.err.println("参数【总请求数】小于了参数【并发数】");
            return;
        }

        //计算需要n1个并发请求的次数
        int count=n2/n1;//eg:n2=100,n1=10,count=10
        List<TestResult> testResults=new ArrayList<TestResult>();
        SimpleDateFormat sdf =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
        //执行n2次总请求【以count次并发请求(每次n1个并发请求)】
        for(int i=0;i<count;i++){
            List<TestResult> subTestResults=new ArrayList<TestResult>();
            for(int j=0;j<n1;j++){
                Runnable runnable=new LoadThread(subTestResults,loadUrl);
                runnable.run();
            }
            while (true){
                if(subTestResults.size()==n1){
                    testResults.addAll(subTestResults);
                    System.out.println(sdf.format(new Date())+":已经完成"+testResults.size()+"个请求");
                    break;
                }
            }
        }
        //计算平均响应时间
        long totalTime=0;
        long successRequet=0;
        for(TestResult testResult:testResults){
            if(testResult.isSuccess()){
                successRequet++;
                totalTime+=testResult.getFinishTime();
            }
        }
        double t=totalTime;
        double s=successRequet;
        double perQuestTime =t/s;

        //计算95%响应时间
        Collections.sort(testResults, new Comparator<TestResult>() {
            public int compare(TestResult o1, TestResult o2) {
                if(o1.getFinishTime()>o2.getFinishTime()){return 1;}
                if(o1.getFinishTime()==o2.getFinishTime()){return 0;}
                if(o1.getFinishTime()<o2.getFinishTime()){return -1;}
                return -1;
            }
        });
        int off= (int)(testResults.size()*0.95);
        long per95QuestTime=testResults.get(off).getFinishTime();

        System.out.println("【本次测试】单次并发数:"+n1+",总请求数:"+n2+",测试url:"+loadUrl+"");
        System.out.println("【本次测试】平均响应时间:"+perQuestTime+"ms,95%响应时间:"+per95QuestTime+"ms");



    }
}